package cn.hackcloud.mutithread.juc;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

public class TestCondition {
    public static void main(String[] args) {
        ConditionDemo demo = new ConditionDemo();
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    demo.loopA();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }, "A").start();
        new Thread(() -> {
            try {
                demo.loopB();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }, "B").start();
    }
}

class ConditionDemo {
    private Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    private volatile int num = 0;
    volatile boolean flag = false;

    public void loopA() throws Exception {
        lock.lock();
        try {
            for (int i = 0; i <= 10; i++) {
                if (i % 2 != 0) {
                    if (num == 0) {
                        condition2.await();
                    }
                    System.out.println(Thread.currentThread().getName() + "\t" + i + "\t");
                    num++;
                    if (num == 2) {
                        condition2.signal();
                    }
                }
            }
        } finally {
            lock.unlock();
        }

    }

    public void loopB() throws Exception {
        lock.lock();
        try {
            for (int i = 1; i <= 10; i++) {
                if (i % 2 == 0) {
                    if (num != 2) {
                        condition2.await();
                    }
                    System.out.println(Thread.currentThread().getName() + "\t" + i + "\t");
                    num = 0;
                    if (num == 0) {
                        condition1.signal();
                    }
                }
            }
        } finally {
            lock.unlock();
        }

    }
}

class Test33 {
    public static void main(String[] args) {
        int[] a = new int[]{2, 1, 3, 9, 4, 11, 13, 15};
        List<Integer> list = Arrays.stream(a).boxed().sorted().collect(Collectors.toList());
        test(list);
    }

    public static void xx(int[] seq) {
        List<Integer> list = Arrays.stream(seq).boxed().sorted().collect(Collectors.toList());
        for (int i = 0; i < list.size(); i++) {

        }
    }

    private void loopA(List<Integer> list, int i) {
        for (int j = 0; j < 2; j++) {

        }
    }

    private void loopB(int i) {

    }

    private static int state = 1;
    private static int num1 = 1;
    private static int num2 = 2;
    int index = 0;

    public static void test(List<Integer> list) {
        final Test33 t = new Test33();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num1 < list.size()) {
//两个线程都bai用t对象作为锁，保证每个交替期du间只有一zhi个线程在打印
                    synchronized (t) {
// 如果state!=1, 说明此时尚未轮到线dao程1打印, 线程1将调用t的wait()方法, 直到下次被唤醒
                        if (state != 1) {
                            try {
                                t.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
// 当state=1时, 轮到线程1打印5次数字
                        for (int j = 0; j < 2; j++) {
                            if (list.get(j) % 2 != 0) {
                                System.out.println(list.get(j));
                            }
                            num1 += 2;
                        }
// 线程1打印完成后, 将state赋值为2, 表示接下来将轮到线程2打印
                        state = 2;
// notifyAll()方法唤醒在t上wait的线程2, 同时线程1将退出同步代码块, 释放t锁
                        t.notifyAll();
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num2 < list.size()) {
                    synchronized (t) {
                        if (state != 2) {
                            try {
                                t.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        for (int j = 0; j < 1; j++) {
                            if (list.get(j) % 2 != 0) {
                                System.out.println(list.get(j));
                            }
                            num2 += 2;
                        }
                        state = 1;
                        t.notifyAll();
                    }
                }
            }
        }).start();
    }
}

class Test34 {
    private static int state = 1;
    private static int num1 = 1;
    private static int num2 = 2;

      void feache() {
        final Test33 t = new Test33();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num1 < 100) {
//两个线程都用t对象作bai为锁，保证每个du交替期间只有zhi一个线程在打印
                    synchronized (t) {
// 如果state!=1, 说明dao此时尚未轮到线程1打印, 线程1将调用t的wait()方法, 直到下次被唤醒
                        if (state != 1) {
                            try {
                                t.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
// 当state=1时, 轮到线程1打印5次数字
                        for (int j = 0; j < 2; j++) {
                            System.out.println(num1);
                            num1 += 2;
                        }
// 线程1打印完成后, 将state赋值为2, 表示接下来将轮到线程2打印
                        state = 2;
// notifyAll()方法唤醒在t上wait的线程2, 同时线程1将退出同步代码块, 释放t锁
                        t.notifyAll();
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (num2 < 100) {
                    synchronized (t) {
                        if (state != 2) {
                            try {
                                t.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        for (int j = 0; j < 1; j++) {
                            System.out.println(num2);
                            num2 += 2;
                        }
                        state = 1;
                        t.notifyAll();
                    }
                }
            }
        }).start();
    }
}